package com.liu.activemq.queue;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;
import java.io.IOException;

public class JmsConsumer {

    //定义MQ发送地址
    public static final String ACTIVEMQ_URL = "tcp://192.168.25.133:61616?jms.useAsyncSend=true";
    //定义队列或主题名
    public static final String QUEUE_NAME = "queue01";

    public static void main(String[] args) throws JMSException, IOException {
        System.out.println("我是2号消费者");

        //创建ActiveMQConnectionFactory，他可以帮我们创建Connection对象
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        activeMQConnectionFactory.setUseAsyncSend(true);
        //创建Connetion对象，他可以帮我们创建Session对象
        Connection connection = activeMQConnectionFactory.createConnection();
        //start方法开启连接

        //创建Session对象，他可以帮我们创建队列queue或者主题topic

        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列queue，其中方法填入我们要获取的队列的名字
        Queue queue = session.createQueue(QUEUE_NAME);
        connection.start();
        //创建出MessageConsumer信息消费者，我们后面要用它来输出队列信息内容
        MessageConsumer consumer = session.createConsumer(queue);
        /**
         * 同步阻塞方式
         * 订阅者或接受者调用MessageConsumer的receive()方法来接受消息，receive方法在接收消息之前（或超时之前）
         * 将一直阻塞
         */
//        while (true){
//            //创建获取信息的对象，这里注意，服务端使用什么类对象来传输数据那么客户端也要使用相应的
//            //类对象来获取队列里的信息
//            /**
//             * 值得一提的是，MessageConsumer有receive()、receive(long var1)、receiveNoWait()
//             * 这三种方法，一个是无限期等待信息队列，第二个是在指定时间内等待信息队列，第三个是不等待信息队列，没有信息就退出
//             */
//            TextMessage receive = (TextMessage)consumer.receiveNoWait();
//            if (null!=receive){
//                System.out.println("消费者接收到信息:"+receive.getText());
//            }else {
//                break;
//            }
//        }
//
//        consumer.close();
//        session.close();
//        connection.close();

        //通过监听的方式来接收消息      MessageConsumer mesc = session.createConsumer(queue)
        /**
         * 异步非阻塞方式（监听器onMessage）
         * 订阅者或接受者通过MessageConsumer的setMessageListener(MessageListerner listerner)注册一个消息监听器
         * 当消息达到之后，系统自动调用监听器MessageLstener的onMessage(essageListener message方法)
         */
        consumer.setMessageListener(new MessageListener() {

            /**
             * Message还有TextMessage、MapMessage、BytesMessage、StreamMessage、ObjectMessage这些实现类
             * 服务端使用哪个实现类来发送数据那么客户端就得用哪个实现类来接收数据
             * 哥哥实现类都有特别的方法
             */
            public void onMessage(Message message) {
                MapMessage map = (MapMessage) message;
                try {
                    //
                    System.out.println(map.getString("k1"));
//                    System.out.println(map.getStringProperty("count"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        //去掉这个read方法实际上就告诉Java不等待MQ获取信息直接关闭，程序从MQ里获取消息需要时间
        System.in.read();
        consumer.close();
        session.close();
        connection.close();

        /**
         * 只启动1号消费者，1号消费者还能获取消息么？Y
         *
         *先启动1号消费者，再启动2号消费者，2号消费者还能消费信息吗？
         * 1号可以消费
         * 2号不可以消费
         *
         * 先启动两个消费者，再生产6个消息，消费情况如何
         *平均分配，两个消费者一人一半
         *
         *MQ挂了，那么信息持久化和丢失情况分别如何
         *
         */

    }
}
